using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System;
using System.Threading;
using System.Text;
using System.IO;


/// <summary>
/// 模块的基类
/// </summary>
public class BaseModule
{
    /// <summary>
    /// Module注册的模式
    /// </summary>
    public enum EnumRegisterMode
    {
        NotRegister,//不需要注册
        AutoRegister,//需要自动注册
        AlreadyRegister,//已经注册
    }

    //定义 对象当前状态 为初始化状态
    private EnumObjectState state = EnumObjectState.Initial;

    //状态设置的处理
    public EnumObjectState State
    {
        get
        {
            return state;
        }
        set
        {
            if (state == value) return;//相同的话，return出去，不要修改

            EnumObjectState oldState = state;//保存以前的状态
            state = value;//新的状态

            if (null != StateChanged)//如果“对应的事件的变化的事件”为空
            {
                StateChanged(this, state, oldState);//调用注册进来的 改变状态的函数
            }
            //子类里重写这个方法就可以监听事件的改变了
            OnStateChanged(state, oldState);
        }
    }

    // 对应的事件的变化（UI对象状态改变的事件，委托类型 : 对象，新的的状态，老的状态。）
    public event StateChangedEvent StateChanged;

    /// <summary>
    /// 子类里重写这个方法就可以监听事件的改变了
    /// 在基类中定义了virtual方法，然后在派生类中使用override重写该方法。那么在对派生类实例的调用中，该虚方法使用的是派生重写的方法。
    /// </summary>
    /// <param name="newState">新的状态</param>
    /// <param name="oldState">旧的状态</param>
    protected virtual void OnStateChanged(EnumObjectState newState, EnumObjectState oldState)
    {

    }

    //注册的模式，默认不需要注册
    private EnumRegisterMode registerMode = EnumRegisterMode.NotRegister;

    /// <summary>
    /// 返回该模块是否需要自动注册
    /// </summary>
    public bool AutoRegister
    {
        get
        {
            return registerMode == EnumRegisterMode.NotRegister ? false : true;//当前模式为“不需要注册”，返回false(不需要注册),反之需要注册。
        }
        set
        {
            if (registerMode == EnumRegisterMode.NotRegister || registerMode == EnumRegisterMode.AutoRegister)//当注册的模式为需要注册，或者不需要注册时
                registerMode = value ? EnumRegisterMode.AutoRegister : EnumRegisterMode.NotRegister;//当输入值为true时，registerMode为自动注册，反之为不需要注册
        }
    }

    /// <summary>
    /// 返回该模块是否已经注册
    /// </summary>
    public bool HasRegistered
    {
        get
        {
            return registerMode == EnumRegisterMode.AlreadyRegister;
        }
    }

    /// <summary>
    /// 用于继承的
    /// 加载函数
    /// </summary>
    public void Load()
    {
        if (State != EnumObjectState.Initial) return;//当前的状态不等于初始化的时候，return出去，代表方法只能在构造初始化的时候进行

        State = EnumObjectState.Loading;//进入Loading状态

        // 当注册模式为 需要自动注册时
        if (registerMode == EnumRegisterMode.AutoRegister)
        {
            ModuleManager.Instance.Register(this);
            // 注册模式变为已经注册
            registerMode = EnumRegisterMode.AlreadyRegister;
        }

        OnLoad();//OnLoad()函数进行数据加载或事件监听
        State = EnumObjectState.Ready;//OnLoad后状态变为准备好的状态
    }

    /// <summary>
    /// 用于重写的
    /// 加载函数
    /// OnLoad()函数进行数据加载或事件监听
    /// </summary>
    protected virtual void OnLoad()
    {

    }

    /// <summary>
    /// 用于继承的
    /// 释放函数
    /// </summary>
    public void Release()
    {
        if (State != EnumObjectState.Disabled)//当状态不为 Disabled隐藏的状态时
        {
            State = EnumObjectState.Disabled;// 把当状态变为 Disabled隐藏状态

            // 当注册模式为已经注册时
            if (registerMode == EnumRegisterMode.AlreadyRegister)
            {
                ModuleManager.Instance.UnRegister(this);
                //注册模式变为 需要自动注册
                registerMode = EnumRegisterMode.AutoRegister;
            }

            OnRelease();//完成资源的一些释放工作
        }
    }

    /// <summary>
    /// 用于重写的
    /// 释放函数
    /// 完成资源的一些释放工作
    /// </summary>
    protected virtual void OnRelease()
    {

    }



    //virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况：

    //情况1：在基类中定义了virtual方法，但在派生类中没有重写该虚方法。那么在对派生类实例的调用中，该虚方法使用的是基类定义的方法。

    //情况2：在基类中定义了virtual方法，然后在派生类中使用override重写该方法。那么在对派生类实例的调用中，该虚方法使用的是派生重写的方法。

}


